<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    :title="getTitle"
    width="50%"
    @ok="handleSubmit"
  >
    <Tabs tab-position="left" @change="handleTabChange" :activeKey="tabActiveKey">
      <template v-for="item in tabsGroupData" :key="item.name">
        <TabPane :tab="item.name">
          <Divider orientation="left" orientationMargin="0">{{ item.name }}</Divider>
        </TabPane>
      </template>
      <BasicTree
        :treeData="treeData"
        :replaceFields="{ title: 'displayName', key: 'name', children: 'permissions' }"
        checkable
        :defaultExpandAll="isExpand"
        ref="treeRef"
        :filterFn="handleFitlerFn"
      />
    </Tabs>
  </BasicModal>
</template>
<script lang="ts">
  import { defineComponent, ref, nextTick, unref } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicTree, TreeActionType, TreeItem } from '/@/components/Tree';
  import { handleTree } from '/@/utils/treeUtil';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { getPermissionList, putPermission } from '/@/api/sys/system';
  import { PermissionInfo } from '/@/api/sys/model/systemModel';
  import { Tabs, TabPane, Divider } from 'ant-design-vue';
  export default defineComponent({
    name: 'RolePermissionModal',
    components: { BasicModal, BasicTree, Tabs, TabPane, Divider },
    emits: ['success', 'register'],
    setup() {
      const { createMessage } = useMessage();
      const treeData = ref([]);
      const isExpand = ref(true);
      const tabActiveKey = ref('');
      const tabsGroupData = ref<TreeItem[]>([]);
      const rowKey = ref('');
      const permissionListData = ref([]);
      const treeRef = ref<Nullable<TreeActionType>>(null);
      function getTree() {
        const tree = unref(treeRef);
        if (!tree) {
          throw new Error('tree is null!');
        }
        return tree;
      }
      const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
        setModalProps({ confirmLoading: false });
        rowKey.value = data.record.name;
        // 需要在setFieldsValue之前先填充treeData，否则Tree组件可能会报key not exist警告 
        const tree_data = (await getPermissionList('R', data.record.name)) as any as PermissionInfo;
        let permissionArray = [];
        let temp_group: any = [];
        let checkIds: any = [];
        tree_data.groups.forEach(function (item: any) {
          temp_group.push(item);
          item.permissions.filter((n: any) => {
            n['group'] = item.name;
            permissionArray.push(n);
            if (n.isGranted) {
              checkIds.push(n.name);
            }
            return n;
          });
        });
        tabsGroupData.value = temp_group;
        permissionListData.value = permissionArray;
        treeData.value = handleTree(permissionArray, 'name', 'parentName', 'permissions');
        //过滤
        tabActiveKey.value = temp_group[0].name;
        nextTick(() => {
          handleTabChange(temp_group[0].name);
          getTree().setCheckedKeys(checkIds);
        });
      });

      const getTitle = '编辑权限';

      async function handleSubmit() {
        try {
          setModalProps({ confirmLoading: true });
          //修改权限
          const checkKeys: string[] = getTree().getCheckedKeys(); 
          let permissions: any = [];
          permissionListData.value.forEach(function (item: any) {
            if (checkKeys.indexOf(item.name) == -1) {
              permissions.push({ name: item.name, isGranted: false });
            } else {
              permissions.push({ name: item.name, isGranted: true });
            }
          });
          //修改权限
          await putPermission('R', rowKey.value, { permissions: permissions });
          createMessage.success('修改成功!');
          closeModal();
        } finally {
          setModalProps({ confirmLoading: false });
        }
      }
      function handleTabChange(activeKey: any) {
        getTree().setSearchValue(activeKey);
        tabActiveKey.value = activeKey;
      }
      function handleFitlerFn(searchValue, node) {
        if (node.group == searchValue) {
          return node;
        }
      }
      return {
        isExpand,
        registerModal,
        handleSubmit,
        getTitle,
        treeData,
        treeRef,
        tabActiveKey,
        tabsGroupData,
        handleTabChange,
        handleFitlerFn,
      };
    },
  });
</script>